/*
 * defines.h
 *
 *  Created on: 04/07/2014
 *      Author: nicolas
 */

#ifndef DEFINES_H_
#define DEFINES_H_

#include "ruta.h"
#include "ipc/Socket.h"

#define CANT_ENTRADAS	4
#define INICIO_CONT_PERS 1000

#define RUTA MI_RUTA "/fuente/defines.h"

#define ID_COLA_COMP		'b'
#define ID_COLA_MSJ			'a'

//#define SALA_SALIDA 		10
//#define SALA_ENTRADA 		20

#define COLASISTEMA 		ID_COLA_MSJ
#define COLARECIBO_CLI		'z'

/******************************************************************************
 *  Char Ids para los IPCS
 *
 ******************************************************************************/

#define ID_SHM_PARQUE					10
#define ID_SHM_SALA_ENT(numSala)		(20 + numSala)
#define INV_ID_SHM_SALA_ENT(idShm)		(idShm - 20)

#define ID_SHM_SALA_ZOO(numSala)		(100 + numSala)
#define INV_ID_SHM_SALA_ZOO(idShm)		(idShm - 100)

#define ID_SHM_TOKEN_COMP				255
#define ID_MTX_TOKEN_COMP				255

#define ID_MUTEX_PARQUE					0
#define INV_ID_MUTEX_PARQUE				0

#define ID_MUTEX_SALA_ENT(numSala)		(1 + numSala)
#define INV_ID_MUTEX_SALA_ENT(idSala)	(idSala - 1)

#define ID_MUTEX_SALA_ZOO(numSala)		(32 + numSala)
#define INV_ID_MUTEX_SALA_ZOO(idSala)	(idSala - 32)

#define ID_SEM_SALA_ENT_LLENO(numSala)		(64 + numSala)
#define INV_ID_SEM_SALA_ENT_LLENO(idSala)	(idSala - 64)

#define ID_SEM_SALA_ZOO_LLENO(numSala)		(96 + numSala)
#define INV_ID_SEM_SALA_ZOO_LLENO(idSala)	(idSala - 96)

#define ID_SEM_BUS(numBUS)				(200 + numBUS)
#define INV_ID_SEM_BUS(idBus)			(idBus - 200)

#define ID_TIMEOOUT_BROKER(numBroker)			(250 - numBroker)
/*********************************************************************************/
// enums
/*********************************************************************************/

namespace Tipos {

enum TipoSala {
	TP_ENTRADA_COLA = 0, TP_ENTRADA_SALA = 1, TP_SALIDA = 2
};

enum LugarDeSala {
	LUGAR_ENTRADA = 0, LUGAR_ZOO = 1
};

enum TipoDePuerta {
	PUERTA_ENTRADA = 0, PUERTA_SALIDA = 1
};

enum EstadoBUS {
	BUS_PARADO = 0, BUS_ACTIVO = 1, BUS_SUBIENDO_PERS = 2, BUS_BAJANDO_PERS = 3
};

enum TipoDeMensaje {
	MSJ_NORMAL = 0,

	MSJ_BUS_ROTO = 1,
	MSJ_PEDIDO_BUS_REPUESTO = 2,
	MSJ_PETICION_CAMBIO_DE_BUS = 3,

	MSJ_ENTRAR_A_PARQUE = 4,
	MSJ_CONFIRMAR_ENTRADA_A_PARQUE = 5,

	MSJ_ENTRAR_COLA_DE_SALA = 6,
	MSJ_ENTRAR_EN_SALA = 7,
	MSJ_CONFIRMAR_ENTRADA_A_SALA = 8,

	MSJ_SUBIR_PERSONA_A_BUS = 9,
	MSJ_CONFIRMAR_SUBIDA_A_BUS = 10,

	MSJ_BAJAR_DE_BUS = 11,
	MSJ_CONFIMAR_BAJADA_DE_BUS = 12,

	MSJ_SALIR_DE_PARQUE = 13,
	MSJ_CONFIRMAR_SALIDA_DE_PARQUE = 14,

	MSJ_IPC = 15,

	MSJ_ANUNCIAR_BUS_REPUESTO = 16,
};

}
;

#define ID_ERROR				-9999
#define CANTMAX 				25
#define CANT_MAX_BUS			50
#define CANT_MAX_PARQUE 		200
#define CANT_BUSES_REPUESTO		20

#define CANT_MAX_BROKERS		10

#define VACIO 0
#define RESERVADO -1

typedef struct {
	int cantPersonas;
	int reservas;
	int personas[CANTMAX]; // 0 = vacio, -1 = reservado, >=1 id de persona
	Tipos::EstadoBUS estadoBUS;
} SALA;

#define LUGAR_VACIO 	 	0
#define LUGAR_RESERVADO 	-1

typedef struct {
	int cantPersonas;
	int ultimoTicket;
	int busesDeRepuestos;
	bool parqueAbierto;
} PARQUE;

#define SALAPETICIONENTRAR 1
#define SALAINFORMARENTRADA 2
#define SALASALIDA 3
#define BUS 4

enum TipoMensaje {
	TIPO_ENVIO_MSG = 0,
	TIPO_TOKEN = 1,
	TIPO_SEM_SIGNAL = 2,
	TIPO_SEM_WAIT = 3,
	TIPO_SALA_LEER_CANTPERSONAS = 4,
	TIPO_SALA_LEER_RESERVAS = 5,
	TIPO_SALA_LEER_PERSONAS = 6,
	TIPO_SALA_LEER_ESTADOBUS = 7,
	TIPO_SALA_ESCRIBIR_CANTPERSONAS = 8,
	TIPO_SALA_ESCRIBIR_RESERVAS = 9,
	TIPO_SALA_ESCRIBIR_PERSONAS = 10,
	TIPO_SALA_ESCRIBIR_ESTADOBUS = 11,
	TIPO_PARQUE_LEER_CANTPERSONAS = 12,
	TIPO_PARQUE_LEER_ULTIMOTICKET = 13,
	TIPO_PARQUE_LEER_BUSESDEREPUESTO = 14,
	TIPO_PARQUE_LEER_PARQUEABIERTO = 15,
	TIPO_PARQUE_ESCRIBIR_CANTPERSONAS = 16,
	TIPO_PARQUE_ESCRIBIR_ULTIMOTICKET = 17,
	TIPO_PARQUE_ESCRIBIR_BUSESDEREPUESTO = 18,
	TIPO_PARQUE_ESCRIBIR_PARQUEABIERTO = 19,
	TIPO_FINALIZAR = 20,
	TIPO_INFO_PID = 21,
	TIPO_LANZAR_BROADCAST = 22,
	TIPO_ESPERAR_BROADCAST = 23,
	TIPO_INTERCONECCION_ANILLO = 24,
	TIPO_REGENERAR_ANILLO = 25,
	TIPO_VERSION_TOKEN = 26
};

typedef struct {
	int id_ipc;
	int num_entidad;
	TipoMensaje op_ipc;

	int posicion_valor;
	int valor;

	int version;

	int resp;
} INFO_IPC;

typedef struct {
	long int destinatario;
	long int origen;
	long int destinatarioFinal;
	int id;
	Tipos::TipoDeMensaje tipo;
	Tipos::LugarDeSala lugar;

	INFO_IPC _ipc;

	bool respuesta;

	unsigned int idMensaje;
} MENSAJE;

#define TAM_MENSAJE		(sizeof(MENSAJE) - sizeof(long int))

/**************************************************************************/
// Mensaje de IPC remoto
/**************************************************************************/

//Broker
enum TipoSem {
	SEM_SALA_ENTRADA = 0,
	SEM_SALA_ZOO = 1,
	SEM_LLENO_ENTRADA = 2,
	SEM_LLENO_ZOO = 3,
	SEM_BUS = 4,
	SEM_PARQUE = 5
};
//TODO
typedef struct {
	PARQUE parque;
	SALA salasEntrada[CANT_ENTRADAS];
	SALA salasZoo[CANT_ENTRADAS];
	bool semParque;
	bool semSalasEntrada[CANT_ENTRADAS];
	bool semSalasZoo[CANT_ENTRADAS];
	bool semSalasLlenoEntrada[CANT_ENTRADAS];
	bool semSalasLlenoZoo[CANT_ENTRADAS];
	bool semBus[CANT_ENTRADAS];
	int version;
	int generacion;
} TOKEN;

#define COLABROKER		'c'
#define COLARESPUESTA	'd'
#define COLATOKEN		'e'

#define DESTINATARIO_ANILLO 50

typedef struct {
	long int destinatario;
	long int destinatarioBroker;
	long int destinatarioFinal;
	long int origen;
	TipoMensaje tipo;
	int id;
	int pid;
	bool esReceptor;
	int idSem;
	int numSala;
	Tipos::LugarDeSala lugarSala;
	int numPersona;
	int valorLeido;
	int valorAEscribir;
	char ip[16];
	int puerto;
	bool primerConeccion;
	unsigned int version;
	unsigned int generacion;
	MENSAJE mensajeOriginal;
} MENSAJE_BROKER;
#define TAM_MENSAJE_BROKER		(sizeof(MENSAJE_BROKER) - sizeof(long int))

typedef struct {
	long int destinatario;
	long int origen;
	TOKEN token;
} MENSAJE_TOKEN;
#define TAM_MENSAJE_TOKEN		(sizeof(MENSAJE_TOKEN) - sizeof(long int))

#endif /* DEFINES_H_ */
